#include "CCFlowInfo.h"

#include <core/Utility.h>

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
// #define new DEBUG_NEW
#endif

// 连续合约切换信息，国债期货

CCCFlowInfo::CCCFlowInfo() {
  memset(m_TFCKey, 0, sizeof(m_TFCKey));
  memset(m_TFCID, 0, sizeof(m_TFCID));
  memset(m_TFCName, 0, sizeof(m_TFCName));
}

CCCFlowInfo::CCCFlowInfo(const char* sTFCKey, const char* sTFCID,
                         const char* sTFCName) {
  memset(m_TFCKey, 0, sizeof(m_TFCKey));
  memset(m_TFCID, 0, sizeof(m_TFCID));
  memset(m_TFCName, 0, sizeof(m_TFCName));
  if (sTFCKey) FIELDCOPY(m_TFCKey, sTFCKey);
  if (sTFCID) FIELDCOPY(m_TFCID, sTFCID);
  if (sTFCName) FIELDCOPY(m_TFCName, sTFCName);
}

CCCFlowInfo::~CCCFlowInfo() {}

void CCCFlowInfo::Clear() {
  memset(m_TFCKey, 0, sizeof(m_TFCKey));
  memset(m_TFCID, 0, sizeof(m_TFCID));
  memset(m_TFCName, 0, sizeof(m_TFCName));
  m_list.clear();
}

void CCCFlowInfo::SetTFCKey(const char* sTFCKey) {
  memset(m_TFCKey, 0, sizeof(m_TFCKey));
  FIELDCOPY(m_TFCKey, sTFCKey);
}

void CCCFlowInfo::SetTFCID(const char* sTFCID) {
  memset(m_TFCID, 0, sizeof(m_TFCID));
  FIELDCOPY(m_TFCID, sTFCID);
}

void CCCFlowInfo::SetTFCName(const char* sTFCName) {
  memset(m_TFCName, 0, sizeof(m_TFCName));
  FIELDCOPY(m_TFCName, sTFCName);
}

const char* CCCFlowInfo::GetTFCKey() { return m_TFCKey; }

const char* CCCFlowInfo::GetTFCID() { return m_TFCID; }

const char* CCCFlowInfo::GetTFCName() { return m_TFCName; }

void CCCFlowInfo::Add(const char* sTFID, const char* TFCDate) {
  CCFLOWINFOUNIT unit;
  unit.TFCDate = (uint32_t)atoi(TFCDate);
  FIELDCOPY(unit.TFID, sTFID);
  m_list.push_back(unit);
  m_list.sort();
}

void CCCFlowInfo::Sort() { m_list.sort(); }

const char* CCCFlowInfo::GetCurrentTFID() const {
  std::list<CCFLOWINFOUNIT>::const_reverse_iterator it = m_list.rbegin();
  if (it == m_list.rend()) return nullptr;
  return it->TFID;
}

uint32_t CCCFlowInfo::GetCurrentDate() {
  std::list<CCFLOWINFOUNIT>::reverse_iterator it = m_list.rbegin();
  if (it == m_list.rend()) return 0;
  return it->TFCDate;
}

const std::list<CCFLOWINFOUNIT>& CCCFlowInfo::GetFlowInfoList() {
  return m_list;
}

//////////////////////////////////////////////////////////////
// class CCCFlowManager
CCCFlowManager::CCCFlowManager() {}

CCCFlowManager::~CCCFlowManager() {}

void CCCFlowManager::Clear() {
  m_TFCIDList.clear();
  m_map.clear();
}

int CCCFlowManager::AddFlowInfo(const char* sTFCKey, const char* sTFCID,
                                const char* sTFCName, const char* sTFID,
                                const char* TFCDate) {
  std::map<std::string, CCCFlowInfo>::iterator it = m_map.find(sTFCID);
  if (it == m_map.end()) {
    CCCFlowInfo info(sTFCKey, sTFCID, sTFCName);
    info.Add(sTFID, TFCDate);
    m_TFCIDList.insert(sTFCID);
    m_map.insert(std::pair<std::string, CCCFlowInfo>(sTFCID, info));
    return 1;
  } else {
    CCCFlowInfo* pInfo = &(it->second);
    if (strcmp(pInfo->GetTFCKey(), sTFCKey) != 0) return -1;
    if (pInfo->GetCurrentDate() < (uint32_t)atoi(TFCDate)) {
      pInfo->SetTFCID(sTFCID);
      pInfo->SetTFCName(sTFCName);
    }
    pInfo->Add(sTFID, TFCDate);
    return 0;
  }
  return -1;
}

const CCCFlowInfo* CCCFlowManager::GetCCFlowInfo(const char* sTFCID) {
  std::map<std::string, CCCFlowInfo>::iterator it = m_map.find(sTFCID);
  if (it == m_map.end()) return NULL;
  return &(it->second);
}

int CCCFlowManager::GetSize() { return m_map.size(); }

const std::set<std::string>& CCCFlowManager::GetTFCIDList() {
  return m_TFCIDList;
}

std::mutex& CCCFlowManager::GetMutex() { return m_mutex; }

int CCCFlowInfo::SizeGetter::GetItemRealSize(const CCCFlowInfo& info) {
  int size = strlen(info.m_TFCKey) + 1;
  size += strlen(info.m_TFCID) + 1;
  size += strlen(info.m_TFCName) + 1;
  return size;
}
int CCCFlowInfo::SizeGetter::GetItemAllSize(const CCCFlowInfo& info) {
  int size = sizeof(CCCFlowInfo);
  size += info.m_list.size() * sizeof(CCFLOWINFOUNIT);
  return size;
}
void CCCFlowManager::DumpStatus(int mode) const {}

CCCFlowManager& CCCFlowManager::instance() {
  static CCCFlowManager s_fm;
  return s_fm;
}
